import json
import os
import re
from os.path import expanduser

import numpy as np
import pandas as pd

from hysdata.models import Query

home = expanduser("~").replace("\\", "/")


def load_config():
    config_path = os.path.join(home, ".hysdata", "config.json")
    if os.path.exists(config_path):
        with open(os.path.join(home, ".hysdata", "config.json")) as f:
            return json.load(f)
    else:
        config_dir = os.path.join(home, ".hysdata")
        if not os.path.exists(config_dir):
            os.makedirs(os.path.join(home, ".hysdata"))
        return {}


def store_config(config: dict):
    with open(os.path.join(home, ".hysdata", "config.json"), 'w', encoding='utf-8') as f:
        json.dump(config, f)


def change_type_and_column_names(df, query: Query = None, cn_column_names=False, change_types=False):
    if not cn_column_names and not change_types:
        return df
    else:
        common_columns = list(
            set(query.return_column_name_dict.keys()).intersection(set(df.columns.values)))
        if change_types:
            df = auto_change_column_dtypes(df)
        if cn_column_names:
            common_columns_name_dict = {col: query.return_column_name_dict[col] for col in common_columns}
            df.rename(columns=common_columns_name_dict, inplace=True)
        return df


def auto_change_column_dtypes(df: pd.DataFrame):
    df = df.convert_dtypes()
    for col in df.columns:
        if 'string' in str(df[col].dtype) or 'object' in str(df[col].dtype):
            s_not_empty: pd.Series = df[col][df[col] != '']
            if len(s_not_empty) > 0:
                str_value = s_not_empty.iloc[0]
                if s_not_empty.str.match("(^[1-9][0-9]+$)|(^[0-9]$)").all() and not (s_not_empty.str.len() == 6).all():
                    df[col] = df[col].replace('', np.nan).astype('Int64')
                elif re.match("^-?[0-9]+[.][0-9]+$", str_value):
                    df[col] = df[col].replace('', np.nan).astype(float)
                elif re.match("^[12][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9]$", str_value):
                    df[col] = pd.to_datetime(df[col])
    return df


__all__ = ["load_config", 'store_config','auto_change_column_dtypes']
